package com.zzf.concurrent.example.thread.group;

import com.zzf.concurrent.example.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author GaoFeng2017
 * @date 2019/8/8 15:20
 */
@Slf4j
public class ThreadGroupExample {
    public static void main(String[] args) {
        // simpleApi();
        complicatedApi();
    }

    private static void complicatedApi() {

        ThreadGroup tg1 = new ThreadGroup("TG1");
        // 设置为守护线程组
        // tg1.setDaemon(true);

        new Thread(tg1 ,() -> {
            log.info("{},I am working...", Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
                // tg1.destroy();
            } catch (InterruptedException e) {
                log.info("{} is interrupted",Thread.currentThread().getName());
            }
        }).start();

        ThreadGroup tg2 = new ThreadGroup(tg1,"TG2");
        new Thread(tg2 ,() -> {
           log.info("{}, I am working in a nest thread group...", Thread.currentThread().getName());
           try {
               Thread.sleep(2000);
           } catch (InterruptedException e) {
               log.info("{} is interrupted",Thread.currentThread().getName());
           }
        }).start();

        TimeUtil.sleep(3000);
        // 中断当前线程组及其子线程组的所有线程
        // tg1.interrupt();

        // tg1.destroy();
        log.info("tg1's is daemon? {}", tg1.isDaemon());
        log.info("tg1's is destroy? {}", tg1.isDestroyed());

    }

    private static void simpleApi() {

        // 默认的parentGroup为main线程的threadGroup
        ThreadGroup tg1 = new ThreadGroup("TG1");
        log.info("{}'s parent is equals main's ThreadGroup? {}", tg1.getName(),
                tg1.getParent() == Thread.currentThread().getThreadGroup());

        Thread t1 = new Thread(tg1, () -> {
            ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
            printThreadGroupInfo(threadGroup);
        });

        t1.start();

        ThreadGroup tg2 = new ThreadGroup("TG2");
        Thread t2 = new Thread(tg2, () -> {
            ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
            printThreadGroupInfo(threadGroup);
            log.info("access parent info, activeCount is {}",threadGroup.getParent().activeCount());
            log.info("access parent info {}", threadGroup.getParent());
            log.info("access tg1 info, activeCount is  {}", tg1.activeCount());
        });

        t2.start();

    }

    private static void printThreadGroupInfo(ThreadGroup threadGroup) {
        log.info("=============== Here are " + threadGroup.getName() +" ThreadGroup's info ===============");
        log.info("name is {}", threadGroup.getName());
        log.info("parent is {}", threadGroup.getParent());
        log.info("maxPriority is {}", threadGroup.getMaxPriority());
        log.info("activeCount is {}", threadGroup.activeCount());
        log.info("is daemon? {}", threadGroup.isDaemon());
        log.info("activeGroupCount is {}", threadGroup.activeGroupCount());
        Thread[] threads = new Thread[threadGroup.activeCount()];
        threadGroup.enumerate(threads);
        log.info("enumerate group threads is {}", threads);
        ThreadGroup[] groups = new ThreadGroup[threadGroup.activeGroupCount()];
        threadGroup.enumerate(groups);
        log.info("enumerate thread groups is {}", groups);
    }
}
